PS 2011 - Laboratorio OS161

Eseguire un programma utente in OS161 (ASST2)

OS/161 contiene un insieme di programmi utente già predisposti per l'esecuzione sul kernel. Questo insieme include programmi di utilità comuni in ambito UNIX, quali ls and cat, oltre a vari altri programmi di test. I sorgenti di tali programmi si trovano, a partire dalla radice dei sorgenti di kernel, in user/{bin,sbin,testbin}.

Molti dei programmi sopra citati non sono in grado di funzionare correttemente, con OS161 nella forma iniziale, in quanto molte “system calls” non sono ancora implementate. Per farli funzionare correttamente occorre quindi implementare tali system calls.

Per creare gli eseguibili dei programmi utente occorre, a partire dai direttori dei file sorgenti, eseguire

make

Gli eseguibili creati, in formato ELF, sono installati nel direttorio pso-os161/root/ nei sotto-direttori bin, sbin e testbin, rispettivamente. Un insieme di programmi eseguibili gà predisposti è presente in tali direttori.

Obiettivo del laboratorio n. 5 è analizzare la fase di “load” di un eseguibile, sino all'avvio dell'esecuzione, NONOSTANTE il programma non funzioni poi correttamente (nel successivo laboratorio si realizzaranno due system calls in grado di supportare INPUT e OUTPUT, permettendo quindi l'esecuzione completa di alcuni programmi di test).

Per analizzare la fase di load e avvio dell'esecuzione di un programma di test, occorre attivare il programma dal menu di os161, mediante il comando “p programma”, ad esempio p testbin/palin”, p sbin/reboot”, dopo aver impostato uno o più breakpoints del debugger, sulle funzioni che eseguono tali operazioni. Si consiglia, ad esempio, di mettere breakpoints su:

common_prog, thread_fork, thread_startup, cmd_progthread, runprogram, load_elf, ...

Si analizzi, in particolare, la fase di attivazione di un nuovo thread e di caricamento del file ELF. Si determini a quali indirizzi di memoria (e come) vengono caricate le parti del file ELF. A tale scopo, si noti che in varie parti del codice sorgente estbdi kernel, compaiono istruzioni del tipo DEBUG(..., che eseguono eventuali kprintf, controllate dal valore della variabile globale dbflags. Per la definizione completa dei valori da assegnare a dbflags, si veda il file kern/include/lib.h. Se ad esempio, si volessero attivare le DEBUG in load_segment, occorrerebbe attivare, in dbflags, il flag DB_EXEC, definito come 0x040. A tale scopo, si può ad esempio usare l'istruzione di gdb: set dbflags = 0x040.

Utilizzando sia le istruzioni DEBUG che GDB, si chiede pertanto di esaminare l'esecuzione di load_elf, di determinare come viene predisposto l' spazio delgli indirizzi del thread in esecuzione (segmento di codice, dati, e stack) e come viene attivata l'esecuzione del programma in user-mode.

Si provi inoltre a verificare quale/quanta memoria viene allocata per il thread in esecuzione, e quale di questa memoria viene rilasciata al termine di tale esecuzione. Quale funzione occorrerebbe modificare per rilasciare tutta la memoria utilizzata ? Sarebbe possibile una minimas modifica al kernel tale da ripristinare lo stato della memoria precedente all'esecuzione del thread ?